﻿using System.Linq.Expressions;
using SqlSugar;
using WeDonekRpc.Model;

namespace WeDonekRpc.SqlSugar
{
    public interface IRepository<T> : IRepository where T : class, new()
    {
        /// <summary>
        /// 申请本地事务
        /// </summary>
        /// <param name="isInherit"></param>
        /// <returns></returns>
        ILocalTransaction ApplyTran ( bool isInherit = true );

        /// <summary>
        /// 根据实体创建表
        /// </summary>
        /// <param name="tableName">表名</param>
        void CreateTable ( string tableName );

        /// <summary>
        /// 根据实体创建表
        /// </summary>
        void CreateTable ();

        /// <summary>
        /// 获取表的唯一键
        /// </summary>
        /// <returns></returns>
        string GetKey ();

        /// <summary>
        /// 获取表的唯一键
        /// </summary>
        /// <returns></returns>
        string[] GetKeys ();

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        bool Delete ( T data );
        /// <summary>
        /// 通过主键ID删除数据
        /// </summary>
        /// <typeparam name="IdentityId">主键类型</typeparam>
        /// <param name="id">主键ID</param>
        /// <returns></returns>
        bool DeleteByKey<IdentityId> ( IdentityId id );
        /// <summary>
        /// 通过主键ID删除多条数据
        /// </summary>
        /// <typeparam name="IdentityId">主键类型</typeparam>
        /// <param name="ids">主键ID</param>
        /// <returns></returns>
        bool DeleteByKey<IdentityId> ( IdentityId[] ids );
        /// <summary>
        /// 更新数据
        /// </summary>
        /// <param name="datas">需更新的数据集</param>
        /// <param name="setCol">设定修改的列</param>
        /// <returns></returns>
        bool UpdateOnly ( T[] datas, Expression<Func<T, object>> setCol );

        /// <summary>
        /// 获取多条数据
        /// </summary>
        /// <typeparam name="Result">结果</typeparam>
        /// <param name="selector">查询结果</param>
        /// <param name="paging">分页和排序的配置</param>
        /// <returns></returns>
        Result[] Gets<Result> ( Expression<Func<T, Result>> selector, IBasicPage paging );
        ISugarQueryable<T> Queryable { get; }
        ISqlQueue<T> BeginQueue ();

        Result Avg<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector );

        Result Max<Result> ( Expression<Func<T, Result>> selector );
        Result Min<Result> ( Expression<Func<T, Result>> selector );

        Result Avg<Result> ( Expression<Func<T, Result>> selector );

        int Count ();
        int Count ( Expression<Func<T, bool>> filter );
        int Count ( string table, Expression<Func<T, bool>> filter );
        int Count ( string table );
        bool Delete ( Expression<Func<T, bool>> filter );
        bool Delete ( Expression<Func<T, bool>> filter, Expression<Func<T, object>> selector, int num );
        IDeleteable<T> Delete ();
        bool Delete<Other> ( Expression<Func<T, Other, bool>> filter ) where Other : class, new();
        T Get ( Expression<Func<T, bool>> filter );
        T GetById<IdentityId> ( IdentityId id );
        Result GetById<IdentityId, Result> ( IdentityId id ) where Result : class;
        Result GetById<IdentityId, Result> ( IdentityId id, Expression<Func<T, Result>> selector );

        T Get ( Expression<Func<T, bool>> filter, string orderby );
        Result Get<Result> ( Expression<Func<T, Result>> selector, string orderby );
        Result Get<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector );
        Result Get<Result> ( Expression<Func<T, bool>> filter ) where Result : class;
        Result Get<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector, string orderby );
        Result Get<Result> ( Expression<Func<T, bool>> filter, string orderby );
        Result Get<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector, Expression<Func<T, object>> orderBy, OrderByType type = OrderByType.Asc );
        T[] GetAll ();
        T[] GetAll ( string orderby );
        Result[] GetAll<Result> ( Expression<Func<T, Result>> selector );
        Result[] GetAll<Result> () where Result : class, new();

        Result[] GetAll<Result> ( Expression<Func<T, Result>> selector, string orderby );

        Result[] GetAll<Result> ( Expression<Func<T, Result>> selector, Expression<Func<T, object>> orderBy, OrderByType type = OrderByType.Asc );
        T[] Gets ( Expression<Func<T, bool>> filter );
        T[] Gets ( Expression<Func<T, bool>> filter, string orderby );
        T[] Gets ( Expression<Func<T, bool>> filter, Expression<Func<T, object>> orderBy, OrderByType type = OrderByType.Asc );

        Result[] Gets<Result> ( Expression<Func<T, bool>> filter ) where Result : class, new();

        Result[] Gets<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector );

        Result[] Gets<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector, string orderby );

        Result[] Gets<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector, Expression<Func<T, object>> orderBy, OrderByType type = OrderByType.Asc );

        Result[] Gets<Result> ( Expression<Func<T, bool>> filter, string orderby ) where Result : class, new();

        Result[] Gets<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, object>> orderBy, OrderByType type = OrderByType.Asc );

        T[] GetsById<IdentityId> ( IdentityId[] ids );

        Result[] GetsById<IdentityId, Result> ( IdentityId[] ids ) where Result : class;

        Result[] GetsById<IdentityId, Result> ( IdentityId[] ids, Expression<Func<T, Result>> selector );

        Result[] GetsById<IdentityId, Result> ( IdentityId[] ids, Expression<Func<T, Result>> selector, string orderBy );

        Result[] GetsById<IdentityId, Result> ( IdentityId[] ids, Expression<Func<T, Result>> selector, Expression<Func<T, object>> orderBy, OrderByType type = OrderByType.Asc );

        Result[] GroupByQuery<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, object>> group, Expression<Func<T, Result>> selector, IBasicPage pager, out int count );
        Result[] GroupBy<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, object>> group, Expression<Func<T, bool>> having, Expression<Func<T, Result>> selector );
        Result[] GroupBy<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, object>> group, Expression<Func<T, Result>> selector );

        Result[] GroupBy<Result> ( Expression<Func<T, object>> group, Expression<Func<T, Result>> selector );
        void Insert ( T item );
        int InsertTable ( List<T> items );
        long InsertReutrnIdentity ( T item );
        void Insert ( T[] items );
        void Insert<Table> ( Table item ) where Table : class, new();
        void Insert<Table> ( Table[] items ) where Table : class, new();

        void Insert ( List<T> items );

        int Insert ( List<T> datas, Expression<Func<T, object>> filter );

        bool IsExist ( Expression<Func<T, bool>> filter );

        bool IsExist ();

        Result[] JoinGroupBy<TInner, Result> ( Expression<Func<T, TInner, bool>> joinExpression,
       Expression<Func<T, TInner, object>> group,
       Expression<Func<T, TInner, Result>> selector ) where TInner : class;

        Result[] JoinGroupBy<TInner, Result> ( Expression<Func<T, TInner, bool>> joinExpression,
        Expression<Func<T, TInner, bool>> filter,
        Expression<Func<T, TInner, object>> group,
        Expression<Func<T, TInner, Result>> selector ) where TInner : class;

        Result JoinGet<TInner, Result> ( Expression<Func<T, TInner, bool>> joinExpression, Expression<Func<T, TInner, bool>> filter, Expression<Func<T, TInner, Result>> selector ) where TInner : class;
        Result JoinGet<TInner, Result> ( Expression<Func<T, TInner, bool>> joinExpression, Expression<Func<T, TInner, Result>> selector ) where TInner : class;
        Result[] Join<TInner, Result> ( Expression<Func<T, TInner, bool>> joinExpression, Expression<Func<T, TInner, Result>> selector ) where TInner : class;
        Result[] Join<TInner, Result> ( Expression<Func<T, TInner, bool>> joinExpression, Expression<Func<T, TInner, bool>> filter, Expression<Func<T, TInner, Result>> selector ) where TInner : class;
        Result[] JoinGroupBy<TInner, TKey, TResult, Result, GroupKey> ( Expression<Func<T, TInner, bool>> joinExpression, Expression<Func<T, TInner, bool>> filter, Expression<Func<T, TInner, object>> group, Expression<Func<T, TInner, Result>> selector ) where TInner : class;
        Result[] JoinQuery<TInner, Result> ( Expression<Func<T, TInner, bool>> joinExpression, Expression<Func<T, TInner, bool>> filter, Expression<Func<T, TInner, Result>> selector, IBasicPage pager, out int count ) where TInner : class;
        Result[] JoinQuery<TInner, Result> ( Expression<Func<T, TInner, bool>> joinExpression, Expression<Func<T, TInner, bool>> filter, Expression<Func<T, TInner, Result>> selector, int index, int size, Expression<Func<T, TInner, object>> orderby, OrderByType byType, out int count ) where TInner : class;
        Result[] JoinQuery<TInner, Result> ( Expression<Func<T, TInner, bool>> join, Expression<Func<T, TInner, Result>> selector, IBasicPage pager, out int count ) where TInner : class;
        Result Max<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector );
        Result Min<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector );
        T[] Query ( Expression<Func<T, bool>> filter, IBasicPage pager, out int count );
        T[] Query ( IBasicPage pager, out int count );
        Result[] Query<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector, IBasicPage pager, out int count );
        Result[] Query<Result> ( Expression<Func<T, bool>> filter, IBasicPage pager, out int count ) where Result : class;
        Result Sum<Result> ( Expression<Func<T, bool>> filter, Expression<Func<T, Result>> selector );
        Result Sum<Result> ( Expression<Func<T, Result>> selector );
        bool Update ( T data, string[] setColumn );
        bool Update ( T data, string[] setColumn, Expression<Func<T, bool>> filter );
        bool Update ( T[] datas, params string[] setColumn );
        bool Update ( string table, T data, params string[] setColumn );
        IUpdateable<T> Update ( T data );
        IUpdateable<T> Updateable ( T[] data );
        IUpdateable<T> Update ();
        IUpdateable<T> Update<Set> ( Set set ) where Set : class;

        /// <summary>
        /// 只能修改单列
        /// </summary>
        /// <param name="columns"></param>
        /// <param name="filter"></param>
        bool Update ( Expression<Func<T, bool>> columns, Expression<Func<T, bool>> filter );
        bool Update<Set> ( Set set, Expression<Func<T, bool>> filter ) where Set : class;

        bool Update<Set> ( Set set, string[] whereColumn ) where Set : class;
        bool Update<Set> ( Set set, Expression<Func<T, object>> whereCols ) where Set : class;

        bool Update<Set> ( Set[] set ) where Set : class;
        bool Update ( T[] datas, Expression<Func<T, object>> whereCols );

        bool Update ( Expression<Func<T, T>> columns, Expression<Func<T, bool>> filter );
        int UpdateRetrunRowNum ( Expression<Func<T, T>> columns, Expression<Func<T, bool>> filter );
        bool Update ( Expression<Func<T, T>> columns, string[] whereColumn );
        bool Update ( Expression<Func<T, T>> columns, Expression<Func<T, object>> whereCols );

        bool Update ( T source, T set );
        bool Update<Set> ( T source, Set set ) where Set : class;

        bool AddOrUpdate ( List<T> datas );
        IStorageable<T> Storageable ( List<T> datas );
        bool AddOrUpdate ( List<T> datas, Expression<Func<T, object>> filter );
        bool AddOrUpdate ( List<T> datas, string table, Expression<Func<T, object>> filter );
        bool AddOrUpdate ( List<T> datas, Func<StorageableInfo<T>, bool> insert, Func<StorageableInfo<T>, bool> update );

        bool AddOrUpdate ( List<T> datas, Expression<Func<T, object>> filter, Expression<Func<T, object>> update );

    }
}